package concurrent.lock;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;

/**
 * @program JavaBase
 * @description:
 * @author: zhanglu
 * @create: 2021-05-16 17:25:00
 */
@Slf4j
public class LockSupportTest {

    /**
     * 若有许可证才可以放行，否则阻塞挂起，默认调用线程是不具有许可证的
     */
    @Test
    public void test01(){
        log.info("begin park");
//        LockSupport.park();
//        LockSupport.park(this);
//        //超时时间，多久之后返回(毫秒)
//        LockSupport.parkNanos(1000 * 1000 * 1000);
//        LockSupport.parkNanos(this, 1000 * 1000 * 1000);
//        //时间戳，到达那个时间点返回(毫秒)
        LockSupport.parkUntil(1621158076000L);
        LockSupport.parkUntil(this, 1621158076000L);
        log.info("end park");
    }

    /**
     * 因为park()被挂起，则调用unpark()该线程会被唤醒，下面这种情况会立马返回
     */
    @Test
    public void test02(){
        log.info("begin park");
        LockSupport.unpark(Thread.currentThread());
        LockSupport.park();
        log.info("end park");
    }

    @Test
    public void test03() throws InterruptedException {
        Thread thread = new Thread(() -> {
            log.info("child thread begin park");
            LockSupport.park();
            log.info("child thread unpark");
        });
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        log.info("main thread begin park");
        LockSupport.unpark(thread);
        log.info("main thread end park");
    }

    /**
     * park()线程被中断返回
     * @throws InterruptedException
     */
    @Test
    public void test04() throws InterruptedException {
        Thread thread = new Thread(() -> {
            log.info("child thread begin park");
            while (!Thread.currentThread().isInterrupted()){
                LockSupport.park();
            }
            log.info("child thread unpark");
        });
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        log.info("main thread begin park");
        thread.interrupt();
        log.info("main thread end park");
    }




}
